Homework5

Author

Haina Qian

Problem 1

(a)

# Library the package we want.
library(Rcpp)
#' @title Define the Rational Class
#' @description Create a class to represent rational numbers (fractions).
#' @slot numerator The numerator of the fraction, must be an integer.
#' @slot denominator The denominator of the fraction, must be an integer and non-zero.
#' @validity Ensures that the denominator is non-zero and both numerator and denominator are integers.
setClass(
  "rational",
  slots = list(
    numerator = "numeric",
    denominator = "numeric"
  ),
  validity = function(object) {
    if (object@denominator == 0) {
      stop("Denominator cannot be zero.")
    }
    if (!is.numeric(object@numerator) || !is.numeric(object@denominator)) {
      stop("Both the numerator and denominator should be numeric.")
    }
    if (object@numerator != floor(object@numerator)) {
      stop(paste0("@numerator = ", object@numerator, " is not a valid numerator (should be an integer)."))
    }
    if (object@denominator != floor(object@denominator)) {
      stop(paste0("@denominator = ", object@denominator, " is not a valid denominator (should be an integer)."))
    }
    TRUE
  }
)

#' @title Construct a Rational Object
#' @description Create a new rational object using a numerator and a denominator.
#' @param numerator The numerator of the fraction (integer).
#' @param denominator The denominator of the fraction (integer, non-zero).
#' @return A rational object.
rational <- function(numerator, denominator) {
  new("rational", numerator = numerator, denominator = denominator)
}

#' @title Display a Rational Object
#' @description Show the rational object in fraction format.
#' @param object A rational object.
#' @return The fraction as a character string.
setMethod("show", "rational", function(object) {
  cat(object@numerator, "/", object@denominator, "\n", sep = "")
})

#' @title Define GCD and LCM in C++
#' @description Use Rcpp to define functions for calculating the greatest common divisor (GCD) and least common multiple (LCM).
cppFunction("
  int gcd(int a, int b) {
    while (b != 0) {
      int temp = b;
      b = a % b;
      a = temp;
    }
    return a;
  }
  
  int lcm(int a, int b) {
    return (a * b) / gcd(a, b);
  }
")

#' @title Simplify a Rational Object
#' @description Reduce a rational object to its simplest form by dividing the numerator and denominator by their GCD.
#' @param object A rational object.
#' @return A simplified rational object.
setGeneric(
  "simplify",
  function(object) standardGeneric("simplify")
)
[1] "simplify"
setMethod(
  "simplify", 
  "rational",
  function(object) {
    gcd_value <- gcd(abs(object@numerator), abs(object@denominator))
    rational(
      numerator = object@numerator / gcd_value,
      denominator = object@denominator / gcd_value
    )
  }
)

#' @title Calculate the Quotient
#' @description Compute the decimal representation of a rational object. Optionally, round to a specified number of digits.
#' @param object A rational object.
#' @param digits (Optional) The number of decimal places to round to. Must be a non-negative integer.
#' @return The computed quotient (invisible).
setGeneric("quotient", function(object, digits = NULL) {
  standardGeneric("quotient")
})
[1] "quotient"
setMethod("quotient", "rational", function(object, digits = NULL) {
  q <- object@numerator / object@denominator
  
  if (!is.null(digits)) {
    if (!is.numeric(digits) || digits < 0 || digits != as.integer(digits)) {
      stop("Digits must be a non-negative integer.")
    }
    formatted_q <- format(round(q, digits), nsmall = digits, scientific = FALSE)
  } else {
    formatted_q <- format(q, scientific = FALSE)
  }
  
  print(formatted_q)
  invisible(q)
})

#' @title Overload the "+" Operator
#' @description Perform addition of two rational objects.
#' @param e1 The first rational object.
#' @param e2 The second rational object.
#' @return A new rational object representing the sum.
setMethod("+", signature(e1 = "rational", e2 = "rational"), function(e1, e2) {
  numerator <- e1@numerator * e2@denominator + e2@numerator * e1@denominator
  denominator <- e1@denominator * e2@denominator
  simplify(new("rational", numerator = numerator, denominator = denominator))
})

#' @title Overload the "-" Operator
#' @description Perform subtraction of two rational objects.
#' @param e1 The first rational object.
#' @param e2 The second rational object.
#' @return A new rational object representing the difference.
setMethod("-", signature(e1 = "rational", e2 = "rational"), function(e1, e2) {
  numerator <- e1@numerator * e2@denominator - e2@numerator * e1@denominator
  denominator <- e1@denominator * e2@denominator
  simplify(new("rational", numerator = numerator, denominator = denominator))
})

#' @title Overload the "*" Operator
#' @description Perform multiplication of two rational objects.
#' @param e1 The first rational object.
#' @param e2 The second rational object.
#' @return A new rational object representing the product.
setMethod("*", signature(e1 = "rational", e2 = "rational"), function(e1, e2) {
  numerator <- e1@numerator * e2@numerator
  denominator <- e1@denominator * e2@denominator
  simplify(new("rational", numerator = numerator, denominator = denominator))
})

#' @title Overload the "/" Operator
#' @description Perform division of two rational objects.
#' @param e1 The first rational object (dividend).
#' @param e2 The second rational object (divisor). The numerator of `e2` must not be zero.
#' @return A new rational object representing the quotient.
setMethod("/", signature(e1 = "rational", e2 = "rational"), function(e1, e2) {
  if (e2@numerator == 0) {
    stop("Division by a rational number with a numerator of 0 detected.")
  }
  numerator <- e1@numerator * e2@denominator
  denominator <- e1@denominator * e2@numerator
  simplify(new("rational", numerator = numerator, denominator = denominator))
})

(b)

# Example Test Cases
r1 <- rational(24, 6)
r2 <- rational(7, 230)
r3 <- rational(0, 4)

# Display examples
r1
24/6
r3
0/4
r1 + r2
927/230
r1 - r2
913/230
r1 * r2
14/115
r1 / r2
920/7
r1 + r3
4/1
r1 * r3
0/1
r2 / r3
Error in r2/r3: Division by a rational number with a numerator of 0 detected.
quotient(r1)
[1] "4"
quotient(r2)
[1] "0.03043478"
quotient(r2, digits = 3)
[1] "0.030"
quotient(r2, digits = 3.14)
Error in quotient(r2, digits = 3.14): Digits must be a non-negative integer.
quotient(r2, digits = "avocado")
Error in quotient(r2, digits = "avocado"): Digits must be a non-negative integer.
q2 <- quotient(r2, digits = 3)
[1] "0.030"
q2
[1] 0.03043478
quotient(r3)
[1] "0"
simplify(r1)
4/1
simplify(r2)
7/230
simplify(r3)
0/1

(c)

# Check some malformed input to my constructor.
rational(2, 0)
Error in validityMethod(object): Denominator cannot be zero.
rational("q", 1)
Error in validObject(.Object): invalid class "rational" object: invalid object for slot "numerator" in class "rational": got class "character", should be or extend class "numeric"
rational(1, "w")
Error in validObject(.Object): invalid class "rational" object: invalid object for slot "denominator" in class "rational": got class "character", should be or extend class "numeric"
rational(1.2, 1)
Error in validityMethod(object): @numerator = 1.2 is not a valid numerator (should be an integer).
rational(1, 1.2)
Error in validityMethod(object): @denominator = 1.2 is not a valid denominator (should be an integer).

Problem 2

(a)

# Library the packages we want.
library(plotly)
library(tidyverse)
# Import the csv.
df <- read.csv("D:/Umich_MAS/semester1/STATS_506/R_work/20241031_hainaq/df_for_ml_improved_new_market.csv")

# Calculate the amount of a certain genre annually.
df2 <- df %>%
  group_by(year) %>%
  summarise(
    Photography = sum(Genre___Photography == 1),
    Print = sum(Genre___Print == 1),
    Sculpture = sum(Genre___Sculpture == 1),
    Painting = sum(Genre___Painting == 1),
    Others = sum(Genre___Others == 1)
    ) %>%
  ungroup()

# Use pivot_longer to better classify the genres of the arts annually.
genres_of_year <- df2 %>%
  pivot_longer(cols = c(Photography, Print, Sculpture, Painting, Others),
               names_to = "Genre", values_to = "Counts")

# Get all years for the xaxis.
all_years <- unique(genres_of_year$year)

# Create a stacked bar chart using Plotly.
fig <- plot_ly(
  data = genres_of_year,
  x = ~year,                
  y = ~Counts,              
  color = ~Genre,
  customdata = ~Genre, 
  colors = c("Photography" = "#7C9D97", "Print" = "#9CB0C3",
             "Sculpture" = "#BD9AAD", "Painting" = "#9193B4",
             "Others" = "#2F2D54"),
  type = "bar",            
  hovertemplate = paste(
    "Year: %{x}<br>",       
    "Count: %{y}<br>",      
    "Genre: %{customdata}<extra></extra>"
  )
) %>%
  layout(
    barmode = "stack",       
    title = list(text = "<b>Distribution of the Genres of the Arts Every Year</b>", 
                 x = 0.5, font = list(size = 20)),
    xaxis = list(
      title = "<b>Year</b>",
      font = list(size = 14),
      tickmode = "array",    
      tickvals = all_years, 
      tickangle = 45        
    ),
    yaxis = list(
      title = "<b>Counts of the Arts</b>",
      font = list(size = 14),
      tickmode = "linear",  
      dtick = 100            
    ),
    legend = list(
      title = list(text = "<b>Genre</b>"),  
      font = list(size = 10)
    ),
    margin = list(t = 50, b = 50) 
  )

# Show the plot.
fig

(b)

# Calculate the average price of each genre in each year.
df3 <- df %>%
  select(year, price_usd, Genre___Photography, Genre___Print, 
         Genre___Sculpture, Genre___Painting, Genre___Others) %>%
  rename(Photography = Genre___Photography, 
         Print = Genre___Print, 
         Sculpture = Genre___Sculpture, 
         Painting = Genre___Painting, 
         Others = Genre___Others) %>%
  pivot_longer(cols = -c(year, price_usd), 
               names_to = "Genre", values_to = "whether_not") %>%
  filter(whether_not == 1) %>%  
  group_by(year, Genre) %>%
  summarise(avg_price = mean(price_usd, na.rm = TRUE), .groups = "drop")

# Calculate the overall average price in each year.
df4 <- df %>%
  group_by(year) %>%
  summarise(avg_price = mean(price_usd, na.rm = T)) %>%
  ungroup() %>%
  mutate(Genre = "Overall")

# Combine the overall average price with each genre's average price.
df_combined <- bind_rows(df3, df4)

# Draw interactive charts using Plotly.
fig <- plot_ly(
  data = df_combined,
  x = ~year,
  y = ~avg_price,
  color = ~Genre,
  colors = c("Overall" = "#397FC7", 
             "Photography" = "#7C9D97", 
             "Print" = "#9CB0C3", 
             "Sculpture" = "#BD9AAD", 
             "Painting" = "#9193B4", 
             "Others" = "#2F2D54"),
  type = 'scatter',
  mode = 'lines+markers',
  line = list(width = 1.2),  
  marker = list(size = 6),   
  hovertemplate = paste(
    "Year: %{x}<br>",
    "Price: $%{y:.2f}<extra></extra>"  
  )
) %>%
  layout(
    title = list(
      text = "<b>Art Sales Price Over Time of Each Genre</b>",  
      x = 0.5,
      font = list(size = 20)
    ),
    xaxis = list(
      title = list(
        text = "<b>Year</b>",  
        font = list(size = 14)
      ),
      tickmode = "linear",
      tickvals = unique(df_combined$year),
      tickangle = 45
    ),
    yaxis = list(
      title = list(
        text = "<b>Average Sales Price (USD)</b>",  
        font = list(size = 14)
      )
    ),
    legend = list(
      title = list(text = "<b>Genre</b>"), 
      font = list(size = 10)
    ),
    margin = list(t = 50, b = 50),  
    hovermode = "closest" 
  )

# Show the plot.
fig

Problem 3

(a)

# Library the packages we want.
library(data.table)
library(nycflights13)
library(kableExtra)
library(knitr)

# Convert to data.table.
flights_dt <- as.data.table(flights)
airports_dt <- as.data.table(airports)

# Add columns with the names of origin and destination airports.
flights_named_dt <- flights_dt[
  airports_dt[, .(faa, name)], 
  on = .(origin = faa), 
  nomatch = 0
][
  , org_name := name
][
  airports_dt[, .(faa, name)], 
  on = .(dest = faa),
  nomatch = 0
][
  , dest_name := name
]

# Calculate departure delays by origin airport.
dep_delay_airport_dt <- flights_named_dt[
  , .(
      mean_dep_delay = mean(dep_delay, na.rm = TRUE),
      median_dep_delay = median(dep_delay, na.rm = TRUE)
    ),
  by = org_name
][
  order(-mean_dep_delay)
]

# Simply print by the property of data.table.
cat("\nMean and Median Departure Delay per Airport\n")

Mean and Median Departure Delay per Airport
print(dep_delay_airport_dt)
              org_name mean_dep_delay median_dep_delay
1: Newark Liberty Intl       15.17009               -1
2: John F Kennedy Intl       12.25837               -1
3:          La Guardia       10.34688               -3
# Generate the departure delay table.
dep_delay_airport_dt %>%
  kable(caption = "Mean and Median Departure Delay per Airport", align = "c") %>%
  kable_styling(full_width = FALSE)
Mean and Median Departure Delay per Airport
org_name mean_dep_delay median_dep_delay
Newark Liberty Intl 15.17009 -1
John F Kennedy Intl 12.25837 -1
La Guardia 10.34688 -3
# Convert to data.table
flights_dt <- as.data.table(flights)
airports_dt <- as.data.table(airports)

# Add origin and destination airport names
flights_named_dt <- flights_dt[
  airports_dt[, .(faa, name)], 
  on = .(origin = faa)
][
  , org_name := name
][
  , name := NULL
][
  airports_dt[, .(faa, name)], 
  on = .(dest = faa)
][
  , dest_name := name
][
  , name := NULL
]

# Calculate mean and median arrival delays per destination airport
arr_delay_airport_dt <- flights_named_dt[
  , .(
      mean_arr_delay = mean(arr_delay, na.rm = TRUE),
      median_arr_delay = median(arr_delay, na.rm = TRUE),
      count = .N
    ),
  by = dest_name
][
  count >= 10  # Filter groups with at least 10 observations
][
  order(-mean_arr_delay)  # Arrange by descending mean_arr_delay
]

# Simply print by the property of data.table.
cat("\nMean and Median Arrival Delay per Airport\n")

Mean and Median Arrival Delay per Airport
print(arr_delay_airport_dt[
  , .(dest_name, mean_arr_delay, median_arr_delay)  # Select columns of interest
])
                               dest_name mean_arr_delay median_arr_delay
 1:                Columbia Metropolitan    41.76415094             28.0
 2:                           Tulsa Intl    33.65986395             14.0
 3:                    Will Rogers World    30.61904762             16.0
 4:                 Jackson Hole Airport    28.09523810             15.0
 5:                        Mc Ghee Tyson    24.06920415              2.0
 6:               Dane Co Rgnl Truax Fld    20.19604317              1.0
 7:                        Richmond Intl    20.11125320              1.0
 8:        Akron Canton Regional Airport    19.69833729              3.0
 9:                      Des Moines Intl    19.00573614              0.0
10:                   Gerald R Ford Intl    18.18956044              1.0
11:                      Birmingham Intl    16.87732342             -2.0
12:         Theodore Francis Green State    16.23463687              1.0
13: Greenville-Spartanburg International    15.93544304             -0.5
14:    Cincinnati Northern Kentucky Intl    15.36456376             -3.0
15:            Savannah Hilton Head Intl    15.12950601             -1.0
16:          Manchester Regional Airport    14.78755365             -3.0
17:                          Eppley Afld    14.69889841             -2.0
18:                               Yeager    14.67164179             -1.5
19:                     Kansas City Intl    14.51405836              0.0
20:                          Albany Intl    14.39712919             -4.0
21:                General Mitchell Intl    14.16722038              0.0
22:                       Piedmont Triad    14.11260054             -2.0
23:               Washington Dulles Intl    13.86420212             -3.0
24:               Cherry Capital Airport    12.96842105            -10.0
25:              James M Cox Dayton Intl    12.68048606             -3.0
26:     Louisville International Airport    12.66938406             -2.0
27:                  Chicago Midway Intl    12.36422360             -1.0
28:                      Sacramento Intl    12.10992908              4.0
29:                    Jacksonville Intl    11.84483416             -2.0
30:                       Nashville Intl    11.81245891             -2.0
31:                Portland Intl Jetport    11.66040210             -4.0
32:               Greater Rochester Intl    11.56064461             -5.0
33:      Hartsfield Jackson Atlanta Intl    11.30011285             -1.0
34:                Lambert St Louis Intl    11.07846451             -3.0
35:                         Norfolk Intl    10.94909344             -4.0
36:            Baltimore Washington Intl    10.72673385             -5.0
37:                         Memphis Intl    10.64531435             -2.5
38:                   Port Columbus Intl    10.60132291             -3.0
39:                  Charleston Afb Intl    10.59296847             -4.0
40:                    Philadelphia Intl    10.12719014             -3.0
41:                  Raleigh Durham Intl    10.05238095             -3.0
42:                    Indianapolis Intl     9.94043412             -3.0
43:            Charlottesville-Albemarle     9.50000000             -5.0
44:               Cleveland Hopkins Intl     9.18161129             -5.0
45:        Ronald Reagan Washington Natl     9.06695204             -2.0
46:                      Burlington Intl     8.95099602             -4.0
47:                 Buffalo Niagara Intl     8.94595186             -5.0
48:                Syracuse Hancock Intl     8.90392501             -5.0
49:                          Denver Intl     8.60650021             -2.0
50:                      Palm Beach Intl     8.56297210             -3.0
51:                             Bob Hope     8.17567568             -3.0
52:       Fort Lauderdale Hollywood Intl     8.08212154             -3.0
53:                          Bangor Intl     8.02793296             -9.0
54:           Asheville Regional Airport     8.00383142             -1.0
55:                      Pittsburgh Intl     7.68099053             -5.0
56:                       Gallatin Field     7.60000000             -2.0
57:                 NW Arkansas Regional     7.46572581             -2.0
58:                           Tampa Intl     7.40852503             -4.0
59:               Charlotte Douglas Intl     7.36031885             -3.0
60:             Minneapolis St Paul Intl     7.27016886             -5.0
61:                      William P Hobby     7.17618819             -4.0
62:                         Bradley Intl     7.04854369            -10.0
63:                     San Antonio Intl     6.94537178             -9.0
64:                      South Bend Rgnl     6.50000000             -3.5
65:     Louis Armstrong New Orleans Intl     6.49017497             -6.0
66:                        Key West Intl     6.35294118              7.0
67:                        Eagle Co Rgnl     6.30434783             -4.0
68:                Austin Bergstrom Intl     6.01990875             -5.0
69:                   Chicago Ohare Intl     5.87661475             -8.0
70:                         Orlando Intl     5.45464309             -5.0
71:               Detroit Metro Wayne Co     5.42996346             -7.0
72:                        Portland Intl     5.14157973             -5.0
73:                        Nantucket Mem     4.85227273             -3.0
74:                      Wilmington Intl     4.63551402             -7.0
75:                    Myrtle Beach Intl     4.60344828            -13.0
76:    Albuquerque International Sunport     4.38188976             -5.5
77:         George Bush Intercontinental     4.24079040             -5.0
78:        Norman Y Mineta San Jose Intl     3.44817073             -7.0
79:               Southwest Florida Intl     3.23814963             -5.0
80:                       San Diego Intl     3.13916574             -5.0
81:              Sarasota Bradenton Intl     3.08243131             -5.0
82:            Metropolitan Oakland Intl     3.07766990             -9.0
83:   General Edward Lawrence Logan Intl     2.91439222             -9.0
84:                   San Francisco Intl     2.67289152             -8.0
85:                         Yampa Valley     2.14285714              2.0
86:              Phoenix Sky Harbor Intl     2.09704733             -6.0
87:            Montrose Regional Airport     1.78571429            -10.5
88:                     Los Angeles Intl     0.54711094             -7.0
89:               Dallas Fort Worth Intl     0.32212685             -9.0
90:                           Miami Intl     0.29905978             -9.0
91:                       Mc Carran Intl     0.25772849             -8.0
92:                  Salt Lake City Intl     0.17625459             -8.0
93:                           Long Beach    -0.06202723            -10.0
94:                Martha\\\\'s Vineyard    -0.28571429            -11.0
95:                  Seattle Tacoma Intl    -1.09909910            -11.0
96:                        Honolulu Intl    -1.36519258             -7.0
97:            John Wayne Arpt Orange Co    -7.86822660            -11.0
98:                    Palm Springs Intl   -12.72222222            -13.5
                               dest_name mean_arr_delay median_arr_delay
# Generate the arrival delay table.
arr_delay_airport_dt[
  , .(dest_name, mean_arr_delay, median_arr_delay)  # Select desired columns
] %>%
  kable(caption = "Mean and Median Arrival Delay per Airport", align = "c") %>%
  kable_styling(full_width = FALSE)
Mean and Median Arrival Delay per Airport
dest_name mean_arr_delay median_arr_delay
Columbia Metropolitan 41.7641509 28.0
Tulsa Intl 33.6598639 14.0
Will Rogers World 30.6190476 16.0
Jackson Hole Airport 28.0952381 15.0
Mc Ghee Tyson 24.0692042 2.0
Dane Co Rgnl Truax Fld 20.1960432 1.0
Richmond Intl 20.1112532 1.0
Akron Canton Regional Airport 19.6983373 3.0
Des Moines Intl 19.0057361 0.0
Gerald R Ford Intl 18.1895604 1.0
Birmingham Intl 16.8773234 -2.0
Theodore Francis Green State 16.2346369 1.0
Greenville-Spartanburg International 15.9354430 -0.5
Cincinnati Northern Kentucky Intl 15.3645638 -3.0
Savannah Hilton Head Intl 15.1295060 -1.0
Manchester Regional Airport 14.7875536 -3.0
Eppley Afld 14.6988984 -2.0
Yeager 14.6716418 -1.5
Kansas City Intl 14.5140584 0.0
Albany Intl 14.3971292 -4.0
General Mitchell Intl 14.1672204 0.0
Piedmont Triad 14.1126005 -2.0
Washington Dulles Intl 13.8642021 -3.0
Cherry Capital Airport 12.9684211 -10.0
James M Cox Dayton Intl 12.6804861 -3.0
Louisville International Airport 12.6693841 -2.0
Chicago Midway Intl 12.3642236 -1.0
Sacramento Intl 12.1099291 4.0
Jacksonville Intl 11.8448342 -2.0
Nashville Intl 11.8124589 -2.0
Portland Intl Jetport 11.6604021 -4.0
Greater Rochester Intl 11.5606446 -5.0
Hartsfield Jackson Atlanta Intl 11.3001128 -1.0
Lambert St Louis Intl 11.0784645 -3.0
Norfolk Intl 10.9490934 -4.0
Baltimore Washington Intl 10.7267338 -5.0
Memphis Intl 10.6453144 -2.5
Port Columbus Intl 10.6013229 -3.0
Charleston Afb Intl 10.5929685 -4.0
Philadelphia Intl 10.1271901 -3.0
Raleigh Durham Intl 10.0523810 -3.0
Indianapolis Intl 9.9404341 -3.0
Charlottesville-Albemarle 9.5000000 -5.0
Cleveland Hopkins Intl 9.1816113 -5.0
Ronald Reagan Washington Natl 9.0669520 -2.0
Burlington Intl 8.9509960 -4.0
Buffalo Niagara Intl 8.9459519 -5.0
Syracuse Hancock Intl 8.9039250 -5.0
Denver Intl 8.6065002 -2.0
Palm Beach Intl 8.5629721 -3.0
Bob Hope 8.1756757 -3.0
Fort Lauderdale Hollywood Intl 8.0821215 -3.0
Bangor Intl 8.0279330 -9.0
Asheville Regional Airport 8.0038314 -1.0
Pittsburgh Intl 7.6809905 -5.0
Gallatin Field 7.6000000 -2.0
NW Arkansas Regional 7.4657258 -2.0
Tampa Intl 7.4085250 -4.0
Charlotte Douglas Intl 7.3603189 -3.0
Minneapolis St Paul Intl 7.2701689 -5.0
William P Hobby 7.1761882 -4.0
Bradley Intl 7.0485437 -10.0
San Antonio Intl 6.9453718 -9.0
South Bend Rgnl 6.5000000 -3.5
Louis Armstrong New Orleans Intl 6.4901750 -6.0
Key West Intl 6.3529412 7.0
Eagle Co Rgnl 6.3043478 -4.0
Austin Bergstrom Intl 6.0199088 -5.0
Chicago Ohare Intl 5.8766148 -8.0
Orlando Intl 5.4546431 -5.0
Detroit Metro Wayne Co 5.4299635 -7.0
Portland Intl 5.1415797 -5.0
Nantucket Mem 4.8522727 -3.0
Wilmington Intl 4.6355140 -7.0
Myrtle Beach Intl 4.6034483 -13.0
Albuquerque International Sunport 4.3818898 -5.5
George Bush Intercontinental 4.2407904 -5.0
Norman Y Mineta San Jose Intl 3.4481707 -7.0
Southwest Florida Intl 3.2381496 -5.0
San Diego Intl 3.1391657 -5.0
Sarasota Bradenton Intl 3.0824313 -5.0
Metropolitan Oakland Intl 3.0776699 -9.0
General Edward Lawrence Logan Intl 2.9143922 -9.0
San Francisco Intl 2.6728915 -8.0
Yampa Valley 2.1428571 2.0
Phoenix Sky Harbor Intl 2.0970473 -6.0
Montrose Regional Airport 1.7857143 -10.5
Los Angeles Intl 0.5471109 -7.0
Dallas Fort Worth Intl 0.3221268 -9.0
Miami Intl 0.2990598 -9.0
Mc Carran Intl 0.2577285 -8.0
Salt Lake City Intl 0.1762546 -8.0
Long Beach -0.0620272 -10.0
Martha\\'s Vineyard -0.2857143 -11.0
Seattle Tacoma Intl -1.0990991 -11.0
Honolulu Intl -1.3651926 -7.0
John Wayne Arpt Orange Co -7.8682266 -11.0
Palm Springs Intl -12.7222222 -13.5

(b)

# Convert to data.table
flights_dt <- as.data.table(flights)
planes_dt <- as.data.table(planes)

# Use data.table's join function to add the model column of planes to flights.
flights_with_model_dt <- merge(flights_dt, planes_dt, by = "tailnum", all.x = TRUE)

# Calculate the average speed and number of flights of the fastest aircraft.
fastest_plane_dt <- flights_with_model_dt[
  , .(flight_times = .N, 
      avg_speed = mean(distance / air_time * 60, na.rm = TRUE)), 
  by = model
][order(-avg_speed)][1][, .(model, avg_speed, flight_times)]

# Simply print by the property of data.table.
print(fastest_plane_dt)
     model avg_speed flight_times
1: 777-222  482.6254            4
# Generate a nice table.
fastest_plane_dt %>%
  setnames(c("avg_speed", "flight_times"), 
           c("average speed(MPH)", "number of flights")) %>%
  kable(caption = "The flight times of the fastest plane", align = "c") %>%
  kable_styling(full_width = FALSE)
The flight times of the fastest plane
model average speed(MPH) number of flights
777-222 482.6254 4